package org.jeecg.modules.simulator.model.line.station.station;

import org.jeecg.modules.simulator.model.line.station.strategy.IExtractionTransferPersonStage;
import org.jeecg.modules.simulator.model.person.Person;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalTime;
import java.util.*;

/**
 * @program: gp2
 * @description:
 * @author: renzhg
 * @create: 2024-08-20 15:33
 **/
public class TransferStation extends Station {

    @Getter
    @Setter
    Map<String, Station> transferStationMap = new HashMap<>(); // lineid, station
    @Getter
    @Setter
    String transferStationId;

    @Getter
    LocalTime operatingStartTime;
    @Getter
    LocalTime operatingCloseTime;
    @Setter
    @Getter
    Map<String,Integer> transferTimeMap=new HashMap<>();//换乘时间设定，Map<线路id-线路id,换乘时间>


    @Setter
    @Getter
    Map<String, List<Person>> transferPersonsMap = new HashMap<>();
    // 人流map
    Map<String, Person> upTransferPersonMap = new HashMap<>();
    Map<String, Person> downTransferPersonMap = new HashMap<>();
    public IExtractionTransferPersonStage extractionTransferPersonStage;//从换乘站的进站人数中提取出从换乘站子站a站的进出口进入，但是到b站上车的人
    // 时长部分
    // 换乘时长




    public void setOperatingStartTime(LocalTime startTime){
            super.setOperatingStartTime(startTime.toString());
            operatingStartTime=startTime;
    }


    public void setOperatingCloseTime(LocalTime closeTime){
        super.setOperatingCloseTime(closeTime.toString());
        operatingStartTime=closeTime;
    }

    public Boolean isInTransferStation(String stationId){

        return transferStationMap.values().stream()
                .anyMatch(value -> value.getId().equals(stationId));

    }
    // 举例子，青年大街
//    {
//        this.line = "1";
//        this.name = "青年大街";
//
//        this.transferStationMap.put("2", {line = "2", name = "青年大街"});
//
//    }

    public TransferStation( String name) {
        super(name);

    }

    @Override
    protected void outside2Inside(LocalTime currentTime, LocalTime now) {
        List<Person> people = this.limitSpeedStage.computedLimitPerson(this.entryExitGateMap, currentTime, now);
        for (Person person : people) {
            person.setCountInputWalkTime(this.walkTime);
            // todo 拆分，根据线路，找出换乘的人
            boolean isTransfer = false;
            if (isTransfer) {
                this.outsidePersonMap.remove(person.getId());
                this.upTransferPersonMap.put(person.getId(), person);
            } else {
                this.outsidePersonMap.remove(person.getId());
                this.walkingPersonMap.put(person.getId(), person);
            }
        }
    }

    /**
     * 换乘站才有此业务
     *
     * @param currentTime
     * @param now
     */
    @Override
    protected void inside2Transfer(LocalTime currentTime, LocalTime now) {

//        List<Station> stationList = new ArrayList<>();
//        for (Station station : stationList) {
//
//            if (station instanceof TransferStation) {
//                TransferStation transferStation = (TransferStation) station;
//                transferStation.getUpTransferPersonMap();
//            }
//
//
//
//        }

        /**
         * @description:这个地方没有写全，换乘站两个子站相互有人进行从1站的进出口进入，但是到2站上车的人，同时有2站的人到1站上车
         * 修改这些人的状态
         *
         * @author: renzhg
         * @date: 2024/8/2 15:12
         **/

        if(this.walkingPersonMap.isEmpty()){
            return;
        }
        List<Person> transferPersons = this.extractionTransferPersonStage.extractTransferPerson(this.walkingPersonMap);

        for (Person person : transferPersons) {
            this.upTransferPersonMap.remove(person.getId());
            transferStationMap.get("2").getWalkingPersonMap().put(person.getId(), person);
        }


    }


    @Override
    public void  handlerInsidePerson(String now) {
        LocalTime localTime = LocalTime.parse(now);
        this.outside2Inside(this.getCurrentTime(), localTime);//进站->走行
        this.inside2Transfer(this.getCurrentTime(), localTime);//换乘动作保留
        super.inside2Platform(this.getCurrentTime(), localTime);//走行->站台

        walkingPersonMap.forEach((k, v) -> {
            v.countDownInputWalkTime();
        });
    }

    @Override
    public void nextTime(String now, Integer step) {
        LocalTime nowTime = LocalTime.parse(now);
        if (!nowTime.isBefore(this.operatingStartTime)) {
            super.nextTime(now, step);
            handlerTransPerson(now);
        }

    }


    /**
     * @description: 换乘的人员进入下一下线路的等待队列
     *
     * @author:  renzhg
     * @date:  2024/9/23 18:08
     **/
    private void handlerTransPerson(String now) {
        List<Person> transferPersonList = getTransferPersonList();
        updateTransferPersonsMap(transferPersonList);
        //region 旧代码
//        List<Person> transferPersonList = new ArrayList<>();
//        transferPersonsMap.forEach((k, v) -> {
//            v.forEach(p -> {
//                p.countDownTransferWalkTime();
//                if (p.getTransferWalkTime() == 0) {
//                    Station nextStation = transferStationMap.get(k.split("-")[1]);
//                    String nextNodeName = p.getNextNodeName(this.name);
//                    nextStation.getWaitingPersonMap().get(nextNodeName).add(p);
//                     transferPersonList.add(p);
//                }
//            });
//        });
//
//
//        transferPersonList.forEach(p -> {
//            transferPersonsMap.get(p.getNextNodeName(this.name)).remove(p);
//        });
        //endregion
    }
    /**
     * 获取已完成换乘步行时间的人员列表。
     *
     * @return 准备换乘到下一站的人员列表
     */
    private List<Person> getTransferPersonList() {
        List<Person> transferPersonList = new ArrayList<>();
        transferPersonsMap.forEach((k, v) -> {
            v.forEach(p -> {
                p.countDownTransferWalkTime();
                if (p.getTransferWalkTime() == 0) {
                    Station nextStation = transferStationMap.get(k.split("-")[1]);
                    String nextNodeName = p.getNextNodeName(this.name);
                    nextStation.getWaitingPersonMap().get(nextNodeName).add(p);
                    transferPersonList.add(p);
                }
            });
        });
        return transferPersonList;
    }

    private void updateTransferPersonsMap(List<Person> transferPersonList) {
        transferPersonList.forEach(p -> {
            transferPersonsMap.get(p.getNextNodeName(this.name)).remove(p);
        });
    }

    @Override
    public LocalTime getCurrentTime() {

        return this.currentTime;
    }
    LocalTime currentTime ;
    @Override
    public void UpdateCurrentTime(LocalTime currentTime) {
        this.currentTime=currentTime;
    }
}
